/*
 * @Author: 侯志伟 
 * @Date: 2019-11-13 16:05:57 
 * @Last Modified by: mikey.zhaopeng
 * @Last Modified time: 2020-07-16 14:14:05
 */
/* eslint-disable */  
import systems from '@/config'
import router from '@/router'
import axios from 'axios'
import { Loading, Message } from 'element-ui'
import Qs from 'qs'
import { getCookie } from './cookieutil'
import fileutil from './fileUtil'
import store from '@/store'
class HttpRequest {
	constructor(baseurl) {
		this.baseURL = baseurl
		this.isError = false
	}
	/**
	 * @param param 转换成formdata的对象
	 * @readonly 创建formData数据
	 */
	getFormdata(param) {
		let formData = new FormData()
		for (var key in param) {
			!Array.isArray(param[key]) ? formData.append(key, param[key]) : param[key].map(item => {
				formData.append(key, item)
			})
		}
		return formData
	}
	/**
	 * @param {getFormdata} 请求实例 
	 */
	setIntercept(instance) {
		let loading = false;
		/**请求拦截 */
		instance.interceptors.request.use(config => {
			let urlIsLoad = config.params && config.params.isLoad || config.data && config.data.isLoad
			/** 当前url是否被拦截加载动画 */
			let isload = systems.loadingIntercept.some(item => { return item && config.url.includes(item) })
			loading = isload || urlIsLoad ? false : Loading.service({
				lock: true,
				text: '努力加载中',
				background: 'rgba(0,0,0,.7)'
			})
			config.url!=='/isvpc/login/identityAuth'?config.headers['accessToken'] = getCookie('accessToken'):''
			return config
		}, error => {
			return Promise.reject(error)
		});
		/**响应拦截 */
		instance.interceptors.response.use(respones => {
			/**关闭加载 */
			loading && 'close' in loading ? loading.close() : null
			/**使按钮可以点击 */
			store.commit('changeDisabled', false)
			/**状态码不是200的错误 */
			if (respones.status !== 200) return Promise.reject("出现一个预期之外的异常,错误代码：" + respones.status)
			/**返回二进制文件 */
			if (respones.config.responseType == 'blob') return respones
			/**请求成功，但是返回警告 */
			if (Number.parseInt(respones.data.code) !== 0 && respones.data.code !=='成功') {
				/** 报错提示拦截 */
				let isDelFail = respones.data.message == '该仓库下还有耗材'  //单独处理删除仓库失败（仓库下有耗材的担示）
				let ismsg = systems.repMsgIntercept.some(item=>{ return item && respones.config.url.includes(item) })
				if(ismsg) return Promise.reject(respones.data.code||respones.data.message)
				if(isDelFail) return Promise.reject(respones.data)
				Message({
					message: respones.data.message,
					type: 'error',
					duration: 3000
				})
				return Promise.reject(respones.data)
			}
			/**成功操作，返回成功提示 */
			if(['获取成功！','success','获取成功','登陆成功！'].indexOf(respones.data.message)==-1){
				Message({ message: respones.data.message, type: 'success', duration: 3000 })
			}
			this.isError = false
			return respones.data.result
		}, error => {
			loading && 'close' in loading ? loading.close() : null
			store.commit('changeDisabled', false)
			if (error && error.response) {
				switch (error.response.status) {
					case 400:
						error.response.msg = "客户端异常"
						break
					case 401:
						error.response.msg = "登录过期,请重新打开应用！"
						break
					case 403:
						error.response.msg = "服务器拒绝访问"
						break
					case 404:
						error.response.msg = "未找到服务地址"
						break
					case 408:
						error.response.msg = "访问超时"
						break
					case 500:
						error.response.msg = "访问服务器失败"
						break
					case 501:
						error.response.msg = "服务器不可用"
						break
					case 502:
						error.response.msg = "服务不可用"
						break
					case 503:
						error.response.msg = "无效请求"
						break
					case 504:
						error.response.msg = "网关超时"
						break
					case 505:
						error.response.msg = "客户端暂不支持该连接"
						break
					default:
						error.response.msg = `请求出错错误代码：${error.response.status}`
						break
				}
				/** 异常状态不给报错 */
				if(this.isError) return Promise.reject(error.response.msg)
				if(error.response.status === 401) return router.replace({ path: '/error',query:{msg:error.response.msg,result:JSON.stringify(error.response.data.result)} })
				Message({
					message: error.response.msg,
					type: 'error',
					duration: 3000,
				})
				this.isError = true
				return Promise.reject(error.response.msg)
			}
			if(this.isError) return Promise.reject('服务器链接出错')
			Message({
				message: '服务器链接出错',
				type: 'error',
				duration: 3000
				
			})
			this.isError = true
			return Promise.reject('服务器链接出错')
		});
	}
	/**av
	 * @param {context} 自定义axios参数
	 * @param {method} 默认指定的请求类型
	 * @param {type} 请求数据编码格式json/www-form-urlencoded/form-data
	 * @param {resultType} 响应类型
	 * @returns {Promise}
	 */
	request(context, method, type, resultType) {
		if (typeof context != 'object' && !Array.isArray(context) && !context.url) {
			// eslint-disable-next-line no-console
			console.error('Api接口参数必须为对象,且url不能为空')
			return
		}
		/**创建请求实例 */
		let executeRequest = axios.create()
		executeRequest.defaults.timeout = 500000
		executeRequest.defaults.baseURL = this.baseURL
		/**设置拦截器 */
		this.setIntercept(executeRequest)
		/**以指定的method为主其次是方法指定最后是默认get */
		context.method = method ? method : (context.method ? context.method : 'GET')
		context.headers = context.headers || {}
		/**仅post put类型需处理数据 */
		let isPostOrPut = 'data' in context && (context.method === 'POST' || context.method === 'PUT')
		/**表单数据编码处理 */
		if (isPostOrPut && type == 'FORM') {
			context.data = Qs.stringify(context.data);
			context.headers['Content-Type'] = 'application/x-www-form-urlencoded'
		}
		/**formdata数据编码处理 */
		if (isPostOrPut && type == 'FORMDATA') {
			context.data = this.getFormdata(context.data)
			context.headers['Content-Type'] = 'multipart/form-data'
		}
		/**设置响应数据类型 */
		resultType ? context.responseType = resultType : ''
		/**执行请求 */
		return executeRequest(context)
	}
	/**
	 * @readonly application/json 提交常规json数据
	 */
	postApi(obj) {
		return this.request(obj, 'POST', 'JSON')
	}
	/**
	 * @readonly application/x-www-form-urlencoded 提交常规表单数据
	 */
	postFormApi(obj) {
		return this.request(obj, 'POST', 'FORM')
	}
	/**
	 * @readonly multipart/form-data 提交表单数据，可上传图片 
	 */
	postFormDataApi(obj) {
		return this.request(obj, 'POST', 'FORMDATA')
	}
	/**
	 * @readonly json数据的put请求
	 */
	putApi(obj) {
		return this.request(obj, 'PUT', 'JSON')
	}
	/**
	 * @readonly 常规表单的put请求
	 */
	putFormApi(obj) {
		return this.request(obj, 'PUT', 'FORM')
	}
	/**
	 * @readonly formdata编码的put请求
	 */
	putFormDataApi(obj) {
		return this.request(obj, 'PUT', 'FORMDATA')
	}
	/**get请求 */
	getApi(obj) {
		return this.request(obj, 'GET', 'JSON')
	}
	/**DELETE请求 */
	delApi(obj) {
		return this.request(obj, 'DELETE', 'JSON')
	}
	/**上传文件-支持多文件传输*/
	upFiles(obj) {
		return this.postFormDataApi(obj)
	}
	/**上传文件-支持多文件传输*/
	putFiles(obj) {
		return this.putFormDataApi(obj)
	}
	/**
	 * @param {fileName} 文件名称
	 */
	downloadFile(obj, fileName) {
		this.request(obj, 'GET', 'JSON', 'blob').then(res => {
			if (!fileName) {
				try {
					fileName = JSON.parse(decodeURI(res.headers['content-disposition'].split('=')[1]))
				} catch (error) {
					fileName = '';
					// eslint-disable-next-line no-console
					console.warn('异常：httpRequest 173行，获取下载文件名称失败，如需自动获取请与后端协商，当未传入fileName时httpRequest默认将其指定为空')
				}
			}
			fileutil.fileReaders(res.data).then(fileUrl => {
				var fileLink = null
				// eslint-disable-next-line no-constant-condition
				if (!typeof Document.createElement === "function") {
					/*IE8以下*/
					fileLink = document.createElement(`<a href="${ fileUrl.length > 2000 ? fileutil.getFileUrl(res.data) : fileUrl }" download="${ fileName }"><a>`)
				} else {
					fileLink = document.createElement("a")
					/**href有长度限制 具体未知 所以如果res大于10W就换方法获取DataUrl */
					fileLink.href = fileUrl.length > 2000 ? fileutil.getFileUrl(res.data) : fileUrl
					fileLink.download = fileName
				}
				fileLink.click()
				fileLink = null
			})
		})
	}
}
export default new HttpRequest(process.env.NODE_ENV !== 'development' ? systems['baseUrl'].pro : systems['baseUrl'].dev)
